#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <fcntl.h>

#define BUF_SIZE 1024
#define NAME_SIZE 256
void error_handling(char *message);
void compute_md5(char *file_name, char *result);

int main(int argc, char *argv[])
{
    int sock;
    char buf[BUF_SIZE];
    struct sockaddr_in serv_adr;
    FILE * fp;
    char file_name[NAME_SIZE];
    char md5[33];

    if (argc != 2) {  
        printf("Usage: %s <filename>\n", argv[0]);  
        exit(EXIT_FAILURE);  
    }  

    sock=socket(PF_INET, SOCK_STREAM, 0);   
    if(sock==-1)
        error_handling("socket() error");

    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family=AF_INET;
    serv_adr.sin_addr.s_addr=inet_addr("127.0.0.1");
    serv_adr.sin_port=htons(8080);

    if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
        error_handling("connect() error!");
    else
        puts("Connected...........");

    // Send file name
    strcpy(file_name, argv[1]);
    write(sock, file_name, NAME_SIZE);

    compute_md5(file_name, md5);
    write(sock, md5, NAME_SIZE);

    fp=fopen(file_name, "rb"); 
    if(fp == NULL)
        error_handling("File open error");

    while(1)
    {
        int read_cnt = fread((void*)buf, 1, BUF_SIZE, fp);
        if(read_cnt < BUF_SIZE)
        {
            write(sock, buf, read_cnt);
            break;
        }
        write(sock, buf, BUF_SIZE);
    }

    // Add shutdown to ensure all data sent to server
    shutdown(sock, SHUT_WR); 
    read(sock, buf, BUF_SIZE); 
    printf("Message from server: %s \n", buf);

    fclose(fp);
     // Compute and print MD5 hash of sent file
    
    compute_md5(file_name, md5);
    printf("MD5 hash of sent file: %s\n", md5);
    close(sock);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}
void compute_md5(char *file_name, char *result)
{
    char cmd[100];
    sprintf(cmd, "md5sum %s", file_name);
    FILE* pipe = popen(cmd, "r");
    if (!pipe) return;
    char* res = fgets(result, 33, pipe);
    if (res == NULL) {
    printf("error\n");
    }
    pclose(pipe);
}
